package org.piggy.core.filter.loadbalance.rule;

import org.piggy.common.config.ServiceInstance;
import org.piggy.common.enums.ResponseCode;
import org.piggy.common.exception.PiggyException;
import org.piggy.core.context.GatewayContext;
import org.piggy.core.manager.DynamicConfigManager;

import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

public class WeightLoadBalanceRule implements LoadBalanceGatewayRule {

    private WeightLoadBalanceRule(){}

    private static final WeightLoadBalanceRule weightLoadBalanceRule = new WeightLoadBalanceRule();

    public static WeightLoadBalanceRule getInstance (){
        return weightLoadBalanceRule;
    }

    @Override
    public ServiceInstance choose(GatewayContext context) {
        Set<ServiceInstance> servers = DynamicConfigManager.getInstance().getServiceInstanceByServiceName(context.getRule().getServiceName(), context.isGray());
        if (servers.isEmpty()) {
            throw new PiggyException(ResponseCode.SERVICE_INSTANCE_NOT_FOUND);
        }
        int totalWeight = 0;
        for (ServiceInstance server : servers) {
            totalWeight = totalWeight + server.getWeight();
        }
        int randomWeight = ThreadLocalRandom.current().nextInt(1, totalWeight + 1);
        for (ServiceInstance instance : servers) {
            randomWeight = randomWeight - instance.getWeight();
            if (randomWeight <= 0) {
                return instance;
            }
        }
        return servers.iterator().next();
    }
}
